//
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#ifndef ZETASQL_PARSER_PARSE_TREE_H_
#define ZETASQL_PARSER_PARSE_TREE_H_

// The complete set of headers comprises 3 parts:
// - ast_node.h is the header for ASTNode, the parent
// - parse_tree_generated.h contains classes generated by gen_parse_tree.py
// - additional miscellany defined in this file.

#include <any>
#include <string>

#include "zetasql/parser/ast_node.h"  
#include "zetasql/parser/ast_node_kind.h"  
#include "zetasql/parser/parse_tree_generated.h"  
#include "zetasql/parser/visit_result.h"
#include "zetasql/public/id_string.h"
#include "zetasql/public/parse_location.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "zetasql/base/ret_check.h"
#include "zetasql/base/status_macros.h"

namespace zetasql {

// This is a fake ASTNode implementation that exists only for tests,
// which may need to pass an ASTNode* to some methods.
class FakeASTNode final : public ASTNode {
 public:
  static constexpr ASTNodeKind kConcreteNodeKind = AST_FAKE;

  FakeASTNode() : ASTNode(kConcreteNodeKind) {}
  explicit FakeASTNode(absl::string_view name)
      : ASTNode(kConcreteNodeKind), name_(name) {}

  absl::string_view name() const { return name_; }

  void Accept(ParseTreeVisitor* visitor, void* data) const override {
    ABSL_LOG(FATAL) << "FakeASTNode does not support Accept";
  }
  absl::Status Accept(ParseTreeStatusVisitor& visitor,
                      std::any& output) const override {
    ZETASQL_RET_CHECK_FAIL() << "FakeASTNode does not support Accept";
  }
  absl::StatusOr<VisitResult> Accept(
      NonRecursiveParseTreeVisitor* visitor) const override {
    ABSL_LOG(FATAL) << "FakeASTNode does not support Accept";
  }

  absl::Status InitFields() final {
    FieldLoader fl(this);
    ZETASQL_RETURN_IF_ERROR(fl.Finalize());
    set_start_location(ParseLocationPoint::FromByteOffset("fake_filename", 7));
    set_end_location(ParseLocationPoint::FromByteOffset("fake_filename", 10));
    return absl::OkStatus();
  }

 private:
  std::string name_;
};

inline IdString ASTAlias::GetAsIdString() const {
  return identifier()->GetAsIdString();
}

}  // namespace zetasql

#endif  // ZETASQL_PARSER_PARSE_TREE_H_
